package com.dragon.logical.service.finance.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.model.ResultCode;
import com.dragon.common.model.exception.CustomException;
import com.dragon.logical.service.customer.CustomerService;
import com.dragon.logical.service.finance.IPaymentService;
import com.dragon.repository.entity.*;
import com.dragon.repository.mapper.OtherFileMapper;
import com.dragon.repository.mapper.PaymentMapper;
import com.dragon.repository.mapper.VendorMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 付款 服务实现类
 * </p>
 *
 * @author sy
 * @since 2023-11-08
 */
@Service
public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment> implements IPaymentService {

    @Autowired
    PaymentMapper paymentMapper;
    @Autowired
    OtherFileMapper fileMapper;
    @Autowired
    CustomerService customerService;

    @Autowired
    VendorMapper vendorMapper;


    @Override
    public Page<Payment> paymentList(Integer page, Integer limit, String search, Integer status, Integer paymentStatus, String startTime, String endTime) {
        Page<Payment> pPage = new Page<>(page, limit);
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        QueryWrapper<Payment> wrapper = new QueryWrapper<>();
        if (StrUtil.isNotEmpty(startTime) || StrUtil.isNotEmpty(endTime)) {
            if (StrUtil.isEmpty(endTime)) {
                endTime = DateUtil.date().toString();
            }
            if (StrUtil.isEmpty(startTime)) {
                startTime = "1999-01-01";
            }
            try {
                df.parse(startTime);
                df.parse(endTime);
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
        wrapper.lambda().like(StrUtil.isNotBlank(search),Payment::getTitle,search)
                .eq(status!=null,Payment::getStatus,status)
                .eq(Payment::getDeleted,0)
                .eq(paymentStatus!=null,Payment::getPaymentStatus,paymentStatus)
                .ge(StrUtil.isNotBlank(startTime), Payment::getCreateTime, startTime)
                .le(StrUtil.isNotBlank(endTime), Payment::getCreateTime, endTime)
                .orderByDesc(Payment::getCreateTime);
        Page<Payment> paymentPage = paymentMapper.selectItems(pPage,wrapper);
        return paymentPage;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public AddPageData addPayment(Payment payment) {
        payment.setCreateTime(DateUtil.date());
        if (payment.getThisTimeMoney() > payment.getMoney()){
            throw new CustomException(ResultCode.PAYMENT_MONEY_IS_INSUFFICIENT);
        }
        paymentMapper.insert(payment);
        //附件
        List<OtherFile> otherFileList = payment.getOtherFileList();
        if (otherFileList != null) {
            otherFileList.forEach(file -> {
                file.setCreateTime(DateUtil.date());
                file.setStreamType(15);
                file.setCorrelationId(payment.getId());
                fileMapper.insert(file);
            });
        }

        AddPageData addPageData = new AddPageData();
        addPageData.setCorrelationId(payment.getId());
        addPageData.setAdminId(payment.getAdminId());
        addPageData.setStreamType(15);
        addPageData.setWorkflowJson(payment.getWorkflowJsonList());
        addPageData.setTitle(payment.getTitle());
        addPageData.setExempt(payment.getExempt()==null?0:1);
        return addPageData;
    }

    @Override
    public void updatePayment(Payment payment) {
        Payment select = paymentMapper.selectById(payment.getId());
        if (select == null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        payment.setUpdateTime(DateUtil.date());
        if (payment.getOtherFileList() != null){
            payment.getOtherFileList().forEach(otherFile -> {
                fileMapper.update(otherFile,new QueryWrapper<OtherFile>().lambda()
                        .eq(OtherFile::getCorrelationId,payment.getId()).eq(OtherFile::getStreamType,15));
            });
        }
        paymentMapper.updateById(payment);
    }

    @Override
    public void deletePayment(Integer id) {
        Payment payment = new Payment();
        payment.setDeleted(1);
        QueryWrapper<Payment> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Payment::getId,id);
        customerService.deleteThorough(15,id);
        paymentMapper.update(payment,wrapper);
    }

    @Override
    public Payment getPaymentById(Integer id) {
        Payment payment = paymentMapper.selectDetailById(id);
        //供应商回款则查询供应商的名称
        if(payment.getType() ==1){
            Vendor vendor = vendorMapper.selectById(payment.getSupplierId());
            payment.setSupplierName(vendor.getName());
        }
        if (payment != null){
            List<OtherFile> otherFiles = fileMapper.selectList(new QueryWrapper<OtherFile>().lambda()
                    .eq(OtherFile::getCorrelationId, id).eq(OtherFile::getStreamType, 15));
            if (otherFiles != null){
                payment.setOtherFileList(otherFiles);
            } else {
                payment.setOtherFileList(new ArrayList<>());
            }
            return payment;
        } else  {
            return new Payment();
        }
    }

    @Override
    public void antiAudit(Integer correlationId){
        QueryWrapper<Payment> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Payment::getId,correlationId).eq(Payment::getStatus,1);
        Payment payment = paymentMapper.selectOne(wrapper);
        payment.setStatus(0);
        paymentMapper.updateById(payment);
    }

    @Override
    public void paymentOperate(Payment payment) {
        Payment select = paymentMapper.selectById(payment.getId());
        if (select == null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        payment.setPaymentStatus(1);
//        if (payment.getOtherFileList() != null){
//            payment.getOtherFileList().forEach(otherFile -> {
//                fileMapper.update(otherFile,new QueryWrapper<OtherFile>().lambda()
//                        .eq(OtherFile::getCorrelationId,payment.getId()).eq(OtherFile::getStreamType,15));
//            });
//        }
        paymentMapper.updateById(payment);
    }

    @Override
    public Map<String,Object> listStatistics(){
        Map<String,Object> data = paymentMapper.selectListStatistics();
        return data;
    }

    @Override
    public  List<PaymentObject> paymentTypePercentage(String time) {
        if (StrUtil.isBlank(time)){
            time = DateUtil.format(DateUtil.date(),"yyyy");
        }
        Map<String, Object> mapData = paymentMapper.paymentTypePercentage(time);
        List<PaymentObject> paymentObjects = new ArrayList<>();
        mapData.keySet().forEach( mapKey ->{
            PaymentObject paymentObject = new PaymentObject();
            paymentObject.setName(mapKey);
            paymentObject.setValue(mapData.get(mapKey));
            paymentObjects.add(paymentObject);
        });
        return paymentObjects;
    }

    @Override
    public LinkedHashMap<String, Object> paymentTotalStatistics(String time) {
        if (StrUtil.isBlank(time)){
            time = DateUtil.format(DateUtil.date(),"yyyy");
        }
        return paymentMapper.paymentTotalStatistics(time);
    }
}
